import { ref } from 'vue'

export const mouse = () => {
  let scaleNum = ref(1)
  // 拖拽、鼠标滚动放大缩小
  const mouseEvent = (target) => {
    /**
     * 判断传入参数是否是HTML DOM
     */
    let isElement = (obj) => {
      return typeof HTMLElement === 'object'
        ? obj instanceof HTMLElement
        : !!(obj && typeof obj === 'object' && (obj.nodeType === 1 || obj.nodeType === 9) && typeof obj.nodeName === 'string')
    }

    /**
     * 被拖拽物、被缩放元素
     */
    let drawEl = target
    /**
     * 如果传入参数不是一个HTML DOM，则查找目标元素
     */
    if (!isElement(target)) {
      drawEl = document.querySelector(target)
    }

    /**
     * 父元素：容器
     */
    const parent = drawEl.parentElement

    /**
     * 获取父元素的大小及其相对于视口的位置。
     */
    const parentRect = parent.getBoundingClientRect()

    /**
     * 鼠标相对于目标物缩放点的距离
     */
    let diffX = 0,
      diffY = 0

    /**
     * 是否正在拖拽
     */
    let isDrawing = false

    /**
     * 鼠标当前相对于父容器的坐标
     */
    let mouseX = 0,
      mouseY = 0

    /**
     * 偏移坐标，缩放比例
     */
    let translateX = 0,
      translateY = 0

    /**
     * 一次缩放的比例
     */
    const diff = 0.1

    /**
     * 滚轮滚动方向是否向上
     * 向上,缩小
     * 向下，放大
     */
    let isUpward = false

    /**
     * 刷新鼠标距离目标元素缩放点的距离
     */
    let refreshMousePositionDiffValue = () => {
      diffX = mouseX - translateX
      diffY = mouseY - translateY
    }

    /**
     * 更新样式
     */
    let refreshTargetStyle = () => {
      drawEl.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scaleNum.value})`
      parent.style.cursor = isDrawing ? 'move' : 'default'
    }

    /**
     * 鼠标移动事件
     */
    parent.addEventListener('mousemove', (e) => {
      mouseX = e.x - parentRect.left
      mouseY = e.y - parentRect.top

      if (isDrawing) {
        translateX = mouseX - diffX
        translateY = mouseY - diffY

        refreshTargetStyle()
      }
    })

    /**
     * 鼠标按下事件
     */
    parent.addEventListener('mousedown', () => {
      refreshMousePositionDiffValue()
      isDrawing = true
      refreshTargetStyle()
    })

    /**
     * 鼠标抬起事件
     */
    window.addEventListener('mouseup', () => {
      isDrawing = false
      refreshTargetStyle()
    })

    /**
     * 鼠标滚动事件
     */

    const mouseZoom = (e) => {
      e = e || window.event
      if (!e.ctrlKey) {
        return
      }
      window.event.preventDefault()
      if (e.wheelDelta) {
        isUpward = e.wheelDelta > 0
      } else if (e.detail) {
        isUpward = e.detail < 0
      }

      let oldWidth = scaleNum.value * drawEl.clientWidth
      let oldHeight = scaleNum.value * drawEl.clientHeight

      if (isUpward) {
        scaleNum.value += diff
      } else if (!isUpward && scaleNum.value > 0.05) {
        scaleNum.value -= diff
      }

      if (scaleNum.value > 2) {
        scaleNum.value = 2
      } else if (scaleNum.value < 0.5) {
        scaleNum.value = 0.4
      }
      let newWidth = scaleNum.value * drawEl.clientWidth
      let newHeight = scaleNum.value * drawEl.clientHeight

      //刷新鼠标距离目标元素缩放点坐标
      refreshMousePositionDiffValue()

      /**
       * 重新计算缩放偏移量
       */
      translateX -= (newWidth - oldWidth) * (diffX / oldWidth)
      translateY -= (newHeight - oldHeight) * (diffY / oldHeight)

      refreshTargetStyle()
    }

    /**
     * 鼠标滚轮兼容
     */

    /*IE、Opera注册事件*/
    if (document.attachEvent) {
      parent.attachEvent('onmousewheel', mouseZoom)
    }
    //Firefox使用addEventListener添加滚轮事件
    if (document.addEventListener) {
      parent.addEventListener('DOMMouseScroll', mouseZoom, false)
    }
    //Safari与Chrome属于同一类型
    window.onmousewheel = parent.onmousewheel = mouseZoom

    /**
     * 页面初始化
     */

    /**
     * 判断缩放元素高度是否高于容器高度
     * 如果大于，则缩放值容器高度
     */
    if (drawEl.clientHeight > parent.clientHeight) {
      scaleNum.value = 1 - (drawEl.clientHeight - parent.clientHeight) / drawEl.clientHeight
    }

    /**
     * 让目标元素居中显示
     */
    translateX = (parent.clientWidth - scaleNum.value * drawEl.clientWidth) / 2
    translateY = (parent.clientHeight - scaleNum.value * drawEl.clientHeight) / 2

    //设置初始样式
    drawEl.style.transformOrigin = '0 0'

    /**
     * 当目标元素 是img时，需要禁用元素鼠标可拖拽
     * div user-drag 默认是none 可以不设置
     */
    drawEl.style.userDrag = 'none'
    drawEl.style.webkitUserDrag = 'none'

    //禁用选则，防止拖拽时出现先择元素内部元素的情况
    drawEl.style.userSelect = 'none'

    refreshTargetStyle()
  }

  /**
   * 点击加减事件
   */

  const onPlusOrMinus = (type) => {
    if (type === 'plus') {
      if (scaleNum.value > 2) {
        return
      }
      scaleNum.value += 0.1
    } else {
      if (scaleNum.value < 0.5) {
        return
      }
      scaleNum.value -= 0.1
    }
  }
  return {
    mouseEvent,
    onPlusOrMinus,
    scaleNum
  }
}
